﻿using Coldairarrow.Business.IT;
using Coldairarrow.Entity.Base_Manage;
using Coldairarrow.Entity.DTO;
using Coldairarrow.Entity.PB;
using Coldairarrow.Entity.TD;
using Coldairarrow.IBusiness;
using Coldairarrow.Util;
using EFCore.Sharding;
using LinqKit;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Linq.Expressions;
using System.Threading.Tasks;

namespace Coldairarrow.Business.TD
{
    public partial class TD_OutStorDetailBusiness : BaseBusiness<TD_OutStorDetail>, ITD_OutStorDetailBusiness, ITransientDependency
    {
        readonly IOperator _operator;
        readonly IOperatorDept _opdept;
        public TD_OutStorDetailBusiness(IDbAccessor db, IServiceProvider svcProvider, IOperator @operator, IOperatorDept @opdept)
            : base(db)
        {
            _ServiceProvider = svcProvider;
            _operator = @operator;
            _opdept = @opdept;
        }
        readonly IServiceProvider _ServiceProvider;

        #region 外部接口

        public async Task<PageResult<TD_OutStorDetail>> GetDataListAsync(PageInput<ConditionDTO> input)
        {
            var q = GetIQueryable();
            var where = LinqHelper.True<TD_OutStorDetail>();
            var search = input.Search;

            //筛选
            if (!search.Condition.IsNullOrEmpty() && !search.Keyword.IsNullOrEmpty())
            {
                var newWhere = DynamicExpressionParser.ParseLambda<TD_OutStorDetail, bool>(
                    ParsingConfig.Default, false, $@"{search.Condition}.Contains(@0)", search.Keyword);
                where = where.And(newWhere);
            }

            return await q.Where(where).GetPageResultAsync(input);
        }

        public async Task<TD_OutStorDetail> GetTheDataAsync(string id)
        {
            return await GetEntityAsync(id);
        }

        public async Task AddDataAsync(TD_OutStorDetail data)
        {
            await InsertAsync(data);
        }

        public async Task UpdateDataAsync(TD_OutStorDetail data)
        {
            await UpdateAsync(data);
        }

        public async Task DeleteDataAsync(List<string> ids)
        {
            await DeleteAsync(ids);
        }
        public async Task<List<TD_OutStorDetailDTO>> GetDataListAsynclist()
        {
            Expression<Func<TD_OutStorDetail, Base_Department, TD_OutStorage, PB_Location, PB_StorArea, PB_Rack, PB_Material,
          Base_User, TD_OutStorDetailDTO>> select = (a, b, c, d, e, f, g, o) => new TD_OutStorDetailDTO
          {

              StorIdName = b.Name,
              LocalIdName = d.Name,
              AreaIdName = e.Name,
              RackIdName = f.Name,
              MaterialIdName = g.Name,
              Codeinfo = c.Id,
              OutType = c.OutType,
              RealName = o.RealName,
              RecordTime = c.OutTime,
          };
           
            select = select.BuildExtendSelectExpre();
            var q = from a in Db.GetIQueryable<TD_OutStorDetail>().AsExpandable()
                    join b in Db.GetIQueryable<Base_Department>() on a.StorId equals b.Id into ab
                    from b in ab.DefaultIfEmpty()
                    join c in Db.GetIQueryable<TD_OutStorage>() on a.OutStorId equals c.Id into ac
                    from c in ac.DefaultIfEmpty()
                    join d in Db.GetIQueryable<PB_Location>() on a.LocalId equals d.Id into ad
                    from d in ad.DefaultIfEmpty()
                    join e in Db.GetIQueryable<PB_StorArea>() on d.AreaId equals e.Id into de
                    from e in de.DefaultIfEmpty()
                    join f in Db.GetIQueryable<PB_Rack>() on d.RackId equals f.Id into df
                    from f in df.DefaultIfEmpty()
                    join g in Db.GetIQueryable<PB_Material>() on a.MaterialId equals g.Id into ag
                    from g in ag.DefaultIfEmpty()
                    join o in Db.GetIQueryable<Base_User>() on a.CreatorId equals o.Id into ao
                    from o in ao.DefaultIfEmpty()
                    select @select.Invoke(a, b, c, d, e, f, g, o);

            var res = q.ToListAsync();
            return await res;
        }
        public async Task<PageResult<TD_OutStorDetail>> GetDataListAsyncs(PageInput<ConditionDTO> input)
        {
            var q = GetIQueryable();
            var where = LinqHelper.True<TD_OutStorDetail>();
            var search = input.Search;

            //筛选
            if (!search.Condition.IsNullOrEmpty() && !search.Keyword.IsNullOrEmpty())
            {
                var newWhere = DynamicExpressionParser.ParseLambda<TD_OutStorDetail, bool>(
                    ParsingConfig.Default, false, $@"{search.Condition}.Contains(@0)", search.Keyword);
                where = where.And(newWhere);
            }

            return await q.Where(where).GetPageResultAsync(input);
        }

        public async Task<PageResult<TD_OutStorDetailDTO>> GetDataListAsyncDtoList(PageInput<TD_OutStorDetailConditonDTO> input)
        {
  
            string sql = @"SELECT
	TD_OutStorage.Id  Codeinfo,
	TD_OutStorage.OutType,
	TD_OutStorDetail.MaterialId,
	TD_OutStorDetail.LocalId,
	Base_EnumItem.`Name`,
	TD_OutStorage.CreateTime RecordTime,
	Department.`Name` StorIdName,
	Area.`Name` AreaIdName,
	Rack.`Name` RackIdName,
	lon.`Name` LocalIdName,
	ifnull(SUM( TD_OutStorDetail.OutNum ),0) OutNum,
	PB_Material.`Name`  MaterialIdName,
	PB_Material.`Code` Code,
	PB_Material.`Spec` Spec,
	u.RealName RealName
FROM
	TD_OutStorage
	LEFT JOIN TD_OutStorDetail ON TD_OutStorDetail.OutStorId = TD_OutStorage.Id
	LEFT JOIN (select * from Base_EnumItem where EnumCode='OutStorageType') Base_EnumItem ON TD_OutStorage.`OutType` = Base_EnumItem.`Code`
	LEFT JOIN PB_Material ON TD_OutStorDetail.MaterialId = PB_Material.Id
	LEFT JOIN PB_Location AS lon ON TD_OutStorDetail.LocalId = lon.Id
	LEFT JOIN PB_Rack AS Rack ON lon.RackId = Rack.Id
	LEFT JOIN PB_StorArea AS Area ON Rack.AreaId = Area.Id
	LEFT JOIN Base_Department AS Department ON Area.StorId = Department.Id 
	LEFT JOIN Base_User AS u on  TD_OutStorage.CreatorId=u.Id
  WHERE 1=1 {0}{1}{2}{3}{4}{5}{6}{7}{8}
GROUP BY 
	TD_OutStorage.Id,
	TD_OutStorDetail.MaterialId,
	TD_OutStorDetail.LocalId,
	Base_EnumItem.`Name`  having   SUM( TD_OutStorDetail.OutNum ) >0  {9}  ";
            
            string Code = "";

            string AreaId = "";
            string Time = "";
            string LoaclName = "";
            string MaterialName = "";
            string RealName = "";
            string RackName = "";
            string StorageName = "";
            string OutType = "";
            string _where = "";
          
            if (!string.IsNullOrEmpty(input.Search.StorageName)) {
                StorageName = "and  Department.Id='"+input.Search.StorageName+"'";
            }
            if (!string.IsNullOrEmpty(input.Search.Code))
            {
                Code = " AND TD_OutStorage.Id  like '%" + input.Search.Code + "%' ";
            }
            if (!string.IsNullOrEmpty(input.Search.StorIdName))
            {
                AreaId = " AND Area.Id ='" + input.Search.StorIdName + "' ";
            }
            if (!string.IsNullOrEmpty(input.Search.StartDate.ToString()) && !string.IsNullOrEmpty(input.Search.EndDate.ToString()))
            {
                Time = " and TD_OutStorage.CreateTime between '" + Convert.ToDateTime(input.Search.StartDate).ToString("yyyy-MM-dd 00:00:00") + "'  and '" + Convert.ToDateTime(input.Search.EndDate).ToString("yyyy-MM-dd 23:59:59") + "'";
            }
            if (!string.IsNullOrEmpty(input.Search.RackName))
            {
                RackName += " and	Rack.`Id` Like '%" + input.Search.RackName + "%'";
            }
            if (!string.IsNullOrEmpty(input.Search.LocalName))
            {
                LoaclName += " and	lon.`Name` Like '%" + input.Search.LocalName + "%'";
            }
            if (!string.IsNullOrEmpty(input.Search.MaterialName))
            {
                MaterialName = "AND( PB_Material.`Name` Like '%" + input.Search.MaterialName + "%' or PB_Material.`Code` Like '%" + input.Search.MaterialName + "%') ";
            }
            if (!string.IsNullOrEmpty(input.Search.OutType))
            {
                OutType = "AND TD_OutStorage.`OutType` Like '%" + input.Search.OutType + "%'";
            }
            if (!string.IsNullOrEmpty(input.Search.RealName))
            {
                RealName = "AND u.`RealName`  Like '%" + input.Search.RealName + "%'";
            }
            if (!input.SortField.IsNullOrEmpty())
            {
                _where += " ORDER BY  TD_OutStorage.CreateTime";
            }
            if (!input.SortType.IsNullOrEmpty())
            {
                _where += " " + input.SortType;
            }
            sql = String.Format(sql,  StorageName, Code, AreaId, Time, RackName, LoaclName, MaterialName, OutType, RealName, _where);
            var res = await Db.GetListBySqlAsync<TD_OutStorDetailDTO>(sql);
            #region   分页处理数据   有bug 没有按照主数据进行处理
            int pagecount;//总页数
            List<TD_OutStorDetailDTO> listpro_down = res.ToList();//一个要分页的，类型数据集合，存储的是所有的数据
            List<TD_OutStorDetailDTO> productes = new List<TD_OutStorDetailDTO>();//用来存储要展示的数据
            int pagees = listpro_down.Count;//所有数据的总条数
                                            //计算总页数
            if (pagees % input.PageRows == 0)
            {
                pagecount = pagees / input.PageRows;
            }
            else
            {
                pagecount = (pagees / input.PageRows) + 1;
            }
            productes = listpro_down.Skip((input.PageIndex - 1) * input.PageRows).Take(input.PageRows).ToList();//分页的重点
            return new PageResult<TD_OutStorDetailDTO> { Data = productes, Total = pagees };
            #endregion
        }
        #endregion

        #region 私有成员

        #endregion
    }
}